/**
 * user控制器
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.controller;


import com.sxf.crm.entity.User;
import com.sxf.crm.dto.RoleDTO;
import com.sxf.crm.dto.StatusUpdateRequest;
import com.sxf.crm.core.entity.Role;
import com.sxf.crm.repository.UserRepository;
import com.sxf.crm.core.repository.RoleRepository;
import com.sxf.crm.service.UserService;
import com.sxf.crm.utils.SecurityUtils;

import lombok.RequiredArgsConstructor;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户控制器
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/6/1
 */
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
    private final UserRepository userRepository;
    private final RoleRepository roleRepository;
    private final UserService userService;

    @PreAuthorize("hasAuthority('user:view') or principal.isAdmin")
    @GetMapping
    public ResponseEntity<Page<UserDTO>> getAllUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String realName,
            @RequestParam(required = false) Integer status) {
        
        PageRequest pageRequest = PageRequest.of(page, size);
        Page<User> users;
        
        if (username != null || realName != null || status != null) {
            users = userRepository.findByUsernameContainingAndRealNameContainingAndStatus(
                username,
                realName,
                status,
                pageRequest
            );
        } else {
            users = userRepository.findAll(pageRequest);
        }
        
        Page<UserDTO> userDTOs = users.map(user -> {
            UserDTO dto = UserDTO.fromUser(user);
            dto.roles = user.getRoles().stream()
                .map(RoleDTO::fromEntity)
                .collect(Collectors.toList());
            return dto;
        });
        
        return ResponseEntity.ok(userDTOs);
    }

    // 查询单个用户
    @PreAuthorize("hasAuthority('user:view') or principal.isAdmin")
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        return userRepository.findById(id)
                .map(UserDTO::fromUser)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    // 新增用户
    @PreAuthorize("hasAuthority('user:add') or principal.isAdmin")
    @PostMapping
    public UserDTO createUser(@RequestBody UserDTO userDTO) {
        User user = new User();
        user.setUsername(userDTO.username);
        user.setPassword(userDTO.password != null ? userDTO.password : "123456"); // 默认密码
        user.setRealName(userDTO.realName);
        user.setPhoneNumber(userDTO.phoneNumber);
        user.setEmail(userDTO.email);
        user.setAvatarUrl(userDTO.avatarUrl);
        user.setDepartmentId(userDTO.departmentId);
        user.setPosition(userDTO.position);
        user.setStatus(userDTO.status != null ? userDTO.status : 1);
        
        // 设置创建和更新信息
        Long currentUserId = SecurityUtils.getCurrentUserId();
        user.setCreateUserId(currentUserId);
        user.setUpdateUserId(currentUserId);
        user.setCreateAt(System.currentTimeMillis());
        user.setUpdateAt(System.currentTimeMillis());
        
        User saved = userRepository.save(user);
        return UserDTO.fromUser(saved);
    }

    // 修改用户
    @PreAuthorize("hasAuthority('user:edit') or principal.isAdmin")
    @PutMapping("/{id}")
    public ResponseEntity<UserDTO> updateUser(@PathVariable Long id, @RequestBody UserDTO userDTO) {
        return userRepository.findById(id).map(user -> {
            user.setRealName(userDTO.realName);
            user.setPhoneNumber(userDTO.phoneNumber);
            user.setEmail(userDTO.email);
            user.setAvatarUrl(userDTO.avatarUrl);
            user.setDepartmentId(userDTO.departmentId);
            user.setPosition(userDTO.position);
            user.setStatus(userDTO.status);
            if (userDTO.password != null && !userDTO.password.isEmpty()) {
                user.setPassword(userDTO.password);
            }
            
            // 设置更新信息
            user.setUpdateUserId(SecurityUtils.getCurrentUserId());
            user.setUpdateAt(System.currentTimeMillis());
            
            User saved = userRepository.save(user);
            return ResponseEntity.ok(UserDTO.fromUser(saved));
        }).orElse(ResponseEntity.notFound().build());
    }

    // 删除用户
    @PreAuthorize("hasAuthority('user:delete') or principal.isAdmin")
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        if (userRepository.existsById(id)) {
            userRepository.deleteById(id);
            return ResponseEntity.ok().build();
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    // 获取用户角色
    @PreAuthorize("hasAuthority('user:view') or principal.isAdmin")
    @GetMapping("/{id}/roles")
    public ResponseEntity<Set<Role>> getUserRoles(@PathVariable Long id) {
        return userRepository.findById(id)
                .map(user -> ResponseEntity.ok(user.getRoles()))
                .orElse(ResponseEntity.notFound().build());
    }

    // 为用户分配角色
    @PreAuthorize("hasAuthority('user:edit') or principal.isAdmin")
    @PutMapping("/{id}/roles")
    public ResponseEntity<UserDTO> assignRoles(@PathVariable Long id, @RequestBody List<Long> roleIds) {
        return userRepository.findById(id).map(user -> {
            Set<Role> roles = roleIds.stream()
                    .map(roleId -> roleRepository.findById(roleId).orElse(null))
                    .filter(role -> role != null)
                    .collect(Collectors.toSet());
            user.setRoles(roles);
            
            // 设置更新信息
            user.setUpdateUserId(SecurityUtils.getCurrentUserId());
            user.setUpdateAt(System.currentTimeMillis());
            
            User saved = userRepository.save(user);
            return ResponseEntity.ok(UserDTO.fromUser(saved));
        }).orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/current")
    public ResponseEntity<?> getCurrentUser(Authentication authentication) {
        String username = authentication.getName();
        User user = userService.findByUsername(username);
        return ResponseEntity.ok(UserDTO.fromUser(user));
    }

    // 修改用户密码
    @PreAuthorize("hasAuthority('user:edit') or principal.isAdmin")
    @PutMapping("/{id}/password")
    public ResponseEntity<?> updatePassword(@PathVariable Long id, @RequestBody PasswordUpdateRequest request) {
        return userRepository.findById(id).map(user -> {
            user.setPassword(request.password);
            
            // 设置更新信息
            user.setUpdateUserId(SecurityUtils.getCurrentUserId());
            user.setUpdateAt(System.currentTimeMillis());
            
            userRepository.save(user);
            return ResponseEntity.ok().build();
        }).orElse(ResponseEntity.notFound().build());
    }

    // 修改用户密码
    @PreAuthorize("hasAuthority('user:edit') or principal.isAdmin")
    @PutMapping("/{id}/status")
    public ResponseEntity<?> updateStatus(@PathVariable Long id, @RequestBody StatusUpdateRequest request) {
        return userRepository.findById(id).map(user -> {
            user.setStatus(request.getStatus());
            
            // 设置更新信息
            user.setUpdateUserId(SecurityUtils.getCurrentUserId());
            user.setUpdateAt(System.currentTimeMillis());
            
            userRepository.save(user);
            return ResponseEntity.ok().build();
        }).orElse(ResponseEntity.notFound().build());
    }

    public static class UserDTO {
        public Long id;
        public String username;
        public String password;
        public String realName;
        public String phoneNumber;
        public String email;
        public String avatarUrl;
        public Long departmentId;
        public String position;
        public Integer status;
        public Long createAt;
        public Long createUserId;
        public Long updateAt;
        public Long updateUserId;
        public List<RoleDTO> roles;

        public static UserDTO fromUser(User user) {
            UserDTO dto = new UserDTO();
            dto.id = user.getId();
            dto.username = user.getUsername();
            dto.realName = user.getRealName();
            dto.phoneNumber = user.getPhoneNumber();
            dto.email = user.getEmail();
            dto.avatarUrl = user.getAvatarUrl();
            dto.departmentId = user.getDepartmentId();
            dto.position = user.getPosition();
            dto.status = user.getStatus();
            dto.createAt = user.getCreateAt();
            dto.createUserId = user.getCreateUserId();
            dto.updateAt = user.getUpdateAt();
            dto.updateUserId = user.getUpdateUserId();
            if(user.getRoles() != null){
                dto.roles = user.getRoles().stream()
                    .map(RoleDTO::fromEntity)
                    .collect(Collectors.toList());
            }
            return dto;
        }
    }


    public static class PasswordUpdateRequest {
        public String password;
    }
} 